package com.gitee.wsl.compose.ui.toast


import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.updateTransition
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalAccessibilityManager
import com.gitee.wsl.compose.ui.base.Toast


@OptIn(ExperimentalAnimationApi::class)
@Composable
fun Toast.ToastView(
    hostState: ToastUIState = LocalToastUIState.current,
    modifier: Modifier = Modifier,
    toastCall: @Composable (ToastData) -> Unit = { Toast(it) },
) {
    val accessibilityManager = LocalAccessibilityManager.current
    val currentData = hostState.currentData ?: return

    key(currentData) {

        var state by remember { mutableStateOf(false) }
        val transition = updateTransition(targetState = state, label = "toast")

        LaunchedEffect(Unit) {
            state = true
            currentData.run(accessibilityManager)
            state = false
        }

        transition.AnimatedVisibility(
            visible = { it },
            modifier = modifier,
            enter = fadeIn() + slideInVertically(),
            exit = fadeOut() + slideOutVertically(),
        ) {
            toastCall(currentData)
        }

        /**
         * 等待完全取消动画和Toast。
         * 此动画解决方法不是使toast数据无效，而是为了防止
         * 当解除动画尚未完成时，重新启动另一个Toast。
         */

        /**
         * 等待完全取消动画和Toast。
         * 此动画解决方法不是使toast数据无效，而是为了防止
         * 当解除动画尚未完成时，重新启动另一个Toast。
         */
        LaunchedEffect(state, transition.currentState, transition.isRunning) {
            if (!state && !transition.currentState && !transition.isRunning) {
                currentData.dismissed()
            }
        }
    }
}